#include "include.h"
#include "func.h"
#include "bsp_uart.h"
#include "func_exspiflash_write.h"
#include "api_spiflash_ex.h"

#if (EX_SPIFLASH_WRITE)
#define MAX_ERASE_BLOCK 20 //400K,
#define ERASE_BLOCK_SIZE 4096

#define MAX_WRITE_BLOCK 8190//1 block =256 byte ,1M byte=4096 block
#define BAUD_RATE 256000
#define MAX_WRITE_index 16
u16 rec_len=0;
u32 w_addr=0;
u16 w_block_cnt=0;
u16 cur_uart_len=0;
u16 cur_w_block;
u8 flash_init_ok=0;
u8 tmp_data[256] AT(.uart_w.buf);;  
u8 check_cnt=0;
void func_spiflash_erase(void)
{
    u16 i;
	printf("start erase spiflash!!\n");
	for(i=0;i<MAX_ERASE_BLOCK;i++)
	{
		spiflash1_erase(i*ERASE_BLOCK_SIZE);
	}
	flash_init_ok=1;
	printf("end erase spiflash!!\n");
	uart1_init(115200);
}
void func_spiflash_write(u16 w_block)
{
	u8* tmp_data;
	u16 i,remain;
	remain=w_block-w_block_cnt;	
	printf("w_block:%d->w_block_cnt:%d->remain:%d\n",w_block,w_block_cnt,remain);
	if(remain>=MAX_WRITE_index)
	{
		printf("w block err!!\n");
		return;
	}
	w_addr=w_block_cnt*256;
	for(i=0;i<remain;i++)
	{
		tmp_data=get_uart_buf(w_block_cnt%MAX_WRITE_index);
		if(w_block_cnt%16==0)
		{
			spiflash1_erase((w_block_cnt/16)*ERASE_BLOCK_SIZE);
		}
		spiflash1_write((void*)tmp_data, w_addr, 256);	
		w_block_cnt++;
		w_addr=w_block_cnt*256;
	}
		
}
void func_spifalsh_read(void)
{
	u16 i,j;
	for (i = 0; i < 50; i++) 
	{
        spiflash1_read(tmp_data,i*256,256);
		printf("block %d :\n",i);
		for(j=0;j<32;j++)
		{
			printf("0x%x ",tmp_data[j]);
		}
		printf("\n");
	}
}
AT(.text.func.write)
void func_uart_data_msg(void)
{
	//u8 i,len;
	func_uart_t *func_uart;
	if(!flash_init_ok)
	{
		return;
	}
	func_uart=get_uart_info();
	if((!func_uart->uart_len)&& (!func_uart->w_block_index))
	{
		return;
	}
	if((!func_uart->w_block_index)&&(func_uart->uart_len!=0))
	{
		//printf("uart_len:%d\n",func_uart->uart_len);
		if(cur_uart_len==0&&func_uart->uart_len!=0)
		{
			cur_uart_len=func_uart->uart_len;
			check_cnt=0;
			return;
		}
		else if(cur_uart_len!=0&&cur_uart_len!=func_uart->uart_len)
		{
			cur_uart_len=func_uart->uart_len;
			check_cnt=0;
			return;
		}
		else if(cur_uart_len==func_uart->uart_len)
		{
			check_cnt++;
			//printf("uart_len:%d\n",func_uart->uart_len);
			if(check_cnt>20)
			{				
				cur_uart_len=0;
				check_cnt=0;
				reset_uart_info();
				printf("trans over!!\n");
			}			
			return;
		}
	}
	else
	{
		if(func_uart->w_block_index!=cur_w_block)
		{
			cur_w_block=func_uart->w_block_index;
			cur_uart_len=func_uart->uart_len;
			check_cnt=0;
			printf("w_block_index:%d\n",func_uart->w_block_index);
			func_spiflash_write(cur_w_block);
			if(func_uart->w_block_index>=MAX_WRITE_BLOCK)
			{
				reset_uart_info();
				cur_w_block=0;
				cur_uart_len=0;
				w_block_cnt=0;
				check_cnt=0;
				uart1_exit();
				mp3_res_play(RES_BUF_EN_UD_FINISH_MP3, RES_LEN_EN_UD_FINISH_MP3);
				#if SYS_KARAOK_EN
				if(sys_cb.mic_onoff)
				{
					bsp_karaok_exit(AUDIO_PATH_KARAOK);
				}
				
				#endif
			}
		}
		else
		{
			if(cur_uart_len!=func_uart->uart_len)
			{
				cur_uart_len=func_uart->uart_len;
				check_cnt=0;
			}
			else
			{
				//printf("cur_uart_len:%d->uart_len:%d\n",cur_uart_len,func_uart->uart_len);
				check_cnt++;
				if(check_cnt>20)
				{
					printf("w_block_index 111:%d\n",func_uart->w_block_index);
					func_spiflash_write(cur_w_block+1);
					reset_uart_info();
					cur_w_block=0;
					cur_uart_len=0;
					w_block_cnt=0;
					check_cnt=0;
					uart1_exit();
					mp3_res_play(RES_BUF_EN_UD_FINISH_MP3, RES_LEN_EN_UD_FINISH_MP3);
					#if SYS_KARAOK_EN
					if(sys_cb.mic_onoff)
					{
						bsp_karaok_exit(AUDIO_PATH_KARAOK);
					}
					#endif
				}
				
			}
		}
	}
	#if 0
	len=get_uart_len();
	if(len==0)
	{
		return;
	}
	if(len<3)
	{
		return;
	}
	
	get_uart_data(tmp_data);
	#if 0
	if(tmp_data[0]!=0xaa&&tmp_data[1]!=0x55)
	{
		return;
	}
	#endif
	for(i=rec_len;i<len;i++)
	{
		printf("uart[%d] :0x%x ",i,tmp_data[i]);
		if(i>100)
		{
			set_uart_len();
			len=0;
			rec_len=0;
			break;
		}
	}
	rec_len+=len;
	#endif
}

AT(.text.func.write)
void func_exspifalsh_write_process(void)
{
    func_process();
	
}


AT(.text.func.write)
void func_exspifalsh_write_mp3_res_play(u32 addr, u32 len)
{
    mp3_res_play(addr, len);
}

AT(.text.func.write)
static void func_exspifalsh_write_enter(void)
{
    msg_queue_clear();	
	spiflash1_init();
	amp_speaker_unmute();
	mp3_res_play(RES_BUF_EN_SPI_MODE_MP3, RES_LEN_EN_SPI_MODE_MP3);
	amp_speaker_mute();
	#if SYS_KARAOK_EN
	if(sys_cb.mic_onoff)
	{
		bsp_karaok_exit(AUDIO_PATH_KARAOK);
	}
	#endif
	reset_uart_info();
	flash_init_ok=1;
	printf("end erase spiflash!!\n");
	uart1_init(BAUD_RATE);
	//func_spiflash_erase();
	//uart1_init(115200);
}

AT(.text.func.write)
static void func_exspifalsh_write_exit(void)
{
    register_spi_read_function(NULL);  //恢复内部SPI读接口.
    uart1_exit();
	#if SYS_KARAOK_EN
	//bsp_karaok_init(AUDIO_PATH_KARAOK, func_cb.sta);
	#endif
    func_cb.last = FUNC_MUSIC;
}
AT(.text.func.music)
void uart_msg_timer(void)
{
    static u32 ticks = 0;

    if(tick_check_expire(ticks,30)){      //100ms记忆一次
        ticks = tick_get();
		func_uart_data_msg();
    }
}

AT(.text.func.write)
void func_exspifalsh_write(void)
{
    printf("%s\n", __func__);
    func_exspifalsh_write_enter();
    while (func_cb.sta == FUNC_EXSPIFLASH_WRITE) {
        func_exspifalsh_write_process();
        func_exspiflash_write_message(msg_dequeue());
		uart_msg_timer();
    }
    func_exspifalsh_write_exit();
}
#endif

